home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Camelot
/
Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip
/
Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf
/
printfx
/
printfx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-06-08
|
10KB
|
373 lines
char *Cr="PrintFx 2.7 09-MAY-89 by D.W.Reisig, NL 1151AV10\n";
char *WTTl=" PrintFx 2.7 ";
/*
This code is a good example how NOT to write a program. Then why
did I include the source?
This is a utility that I made when I had the Amiga one month or so.
And I could not get my files to my printer without printing over
the perforation, or it stopped halfway the sheet when the printing
was done. Annyway I got irritated.
I have an Epson FX80+. I thought that made this program useless
for other printers. Suddenly the hole world can use it on their
printers as well. This is why I included the source. Perhaps it
does not work on your printer. Now you can change it (if you can
decipher the code).
I used Lattice 5.02 and Asm 5.02 as compilers but 4.00 does it also
fine.
*/
#include <libraries/dos.h>
#include <setjmp.h>>
#include <exec/types.h>
#include <intuition/intuition.h>
#define CMDNAMES 1 /* one inputfile */
#define ISM 64 /* init string max */
#define IOBUFFER 512 /* twice allocated from the stack */
#define RMARGINIT 255 /* means: not used */
#define UNIT_INCH 216 /* there are 216 1/3 units in a inch */
#define EOF -1 /* */
#define ESC 0x1b /* */
#define SKIPOVERA 198 /* skip-over space in 1/3 dots if back shift */
#define SKIPOVERB 264 /* skip-over space if not shifted back */
#define PERFSHIFT 54 /* paper shift back at start in 1/3 dots */
#define ERROR -1 /* Used with longjump in an error situation */
#define STOP 1 /* Used with longjump in a non error situation */
jmp_buf Mains; /* easy does it */
char DeinitPaper[]={ ESC,'J',PERFSHIFT,ESC,'C',0,0 } ;
#define DEINITLEN 7 /* size of DeinitPaper[] */
char *Path[CMDNAMES+1];
char *Title=NULL; /* title available */
int Infile; /* DOS file handler */
int Prt; /* DOS file handler */
int Page=0; /* printer determines pagelength */
int Lmarg=5; /* left margin */
int Rmarg=RMARGINIT; /* right margin not given */
int Cpline; /* will contain number of possible chars/line */
int Mode=64; /* 64=unused */
int Lsp=29; /* Linespace .13456" 3.41mm 82 l/p */
int Type=1; /* type is elite */
int Plen=11; /* paper length in inches */
int SpPTab=8; /* Spaces per Tab (make an option of it iyl */
char *Pr; /* Name of this utility from cmdline */
char Cond=0; /* not condensed */
char Empha=0; /* not emphasized */
char Double=0; /* not double strike */
char Prop=0; /* not proportional */
char Super=0; /* super script is off */
char Trunc=1; /* truncation line overflow */
char PlBack=1; /* paper is pulled back at start */
char EndDet=1; /* paper end detection on */
char OutStd=0; /* Output not standard; PAR: */
char Let='\f'; /* last character send to printer, if it is FF, */
/* no extra FF must be sent, and no FF if */
/* nothing has been printed */
char Er=1; /* stderr may be used */
void ps(),ErrMsg(),Explain();
char gc();
extern int ConOut;
main(argc,argv)
register int argc;
register char *argv[];
{
register int argcnt, namecnt, ret, err=0;
Pr=argv[0]; /* adapt name the user uses */
if (argc>1){
if (*argv[1]=='?'){
Explain();
return(0);
}
}
for (argcnt=1,namecnt=0;argcnt<argc;++argcnt) if (*(argv[argcnt])!='-'){
Path[namecnt++]=argv[argcnt];
if (namecnt>CMDNAMES) break;
}
procopts(argc,argv);
if (namecnt>CMDNAMES){
ErrMsg("Donot know what to do with: ",Path[CMDNAMES]);
return(0);
}
if (calc()) return(0); /* some things must be calculated */
if (Path[0]){
if ((Infile=Open(Path[0],MODE_OLDFILE))==0){
ErrMsg("Cannot open: ",Path[0]);
return(0);
}
} else Infile=Input();
if (!OutStd){
if ((Prt=Open("PAR:",MODE_OLDFILE))==0){
ErrMsg("No printer (PAR:)","");
goto CleanUp;
}
} else Prt=Output();
ret=setjmp(Mains); /* return point from deep level errors */
if (ret) goto CleanUp;
MakeOffSwitch(WTTl); /* nice to stop when you did RUN pr.. */
initprinter();
filetoprinter();
deinitprinter();
goto CleanUp1;
CleanUp:
if (ret==ERROR) err=IoErr();
CleanUp1:
RemOffSwitch();
if (!OutStd) Close(Prt);
if (Path[0]) Close(Infile);
return(err);
} /* main */
procopts(argc,argv)
register int argc;
register char *argv[];
{
register int argcnt;
register char *option, *error, avail;
int temp;
for (argcnt=1;argcnt<argc;++argcnt){
if (*(option=argv[argcnt])=='-'){
avail=1;
while (avail) switch(*(error=option++)){
case '-' : break;
case '\0' : avail=0; break;
case '?' : if (*option=='?') ConMsg(Cr); else Explain(); XCEXIT(0);
case 't' : Title =(*option=='=')?option+1:option; avail=0; break;
case 'i' : option+=stoi(option,&Plen); break;
case 'l' : option+=stoi(option,&Lmarg); break;
case 'r' : option+=stoi(option,&Rmarg); break;
case 'p' : option+=stoi(option,&temp);
if (temp==0) Type&=0xfe;
else Page=temp;
break;
case 'm' : option+=stoi(option,&Mode); break;
case 'n' : option+=stoi(option,&Lsp); break;
case 'c' : Type|=0x04; break;
case 'e' : switch(*(option++)){
case 'd' : EndDet=0; break;
case 'l' : Type|=0x01; break;
case 'm' : Type|=0x08; break;
case 'n' : Type|=0x20; break;
default : goto opterr;
}
case 'd' : Type|=0x10; break;
case 'v' : Prop=1; break;
case 'x' : Trunc=0; break;
case 'y' : PlBack=0; break;
case 'o' : OutStd=1; break;
case 's' : Er=0; break;
case 'q' : Super=1; break;
default : goto opterr;
} } } return(0);
opterr:
Explain();
ErrMsg("Unknown option: -",error);
XCEXIT(0);
} /* procopts */
calc()
{
register int choose, avail;
register unsigned char *data;
if (Mode==64) Mode=Type;
data="\x50\x60\x28\x30\x89\xA0\x44\x50";
choose=(int)Mode&0x05; /* b0 on is elite, b2 on is condensed */
if (Mode&0x20) choose+=0x02; /* b1 on is enlarged */
Cpline=(int)*(data+choose);
if (Rmarg!=RMARGINIT){
if (Rmarg>Cpline){
ErrMsg("Right margin too large","");
return(-1);
}
} else Rmarg=Cpline;
Cpline=Rmarg-Lmarg;
avail=((Plen*UNIT_INCH)-((PlBack)?SKIPOVERA:SKIPOVERB))/Lsp;
if (Page){
if (Page>avail){
ErrMsg("You ask too much lines per page","");
return(-1);
}
} else Page=avail;
return(0);
}
initprinter()
{
char initstring[ISM];
register char *is=initstring;
register int len;
if (PlBack){
*(is++)=ESC; *(is++)='j'; *(is++)=PERFSHIFT;
}
*(is++)=ESC; *(is++)='@';
*(is++)=ESC; *(is++)='C'; *(is++)=0; *(is++)=Plen;
*(is++)=ESC; *(is++)='!'; *(is++)=Mode;
if (Prop) { *(is++)=ESC; *(is++)='p'; *(is++)='1'; }
*(is++)=ESC; *(is++)=EndDet?'9':'8';
*(is++)=ESC; *(is++)='3'; *(is++)=Lsp;
if (Lmarg) { *(is++)=ESC; *(is++)='l'; *(is++)=Lmarg; }
*(is++)=ESC; *(is++)='Q'; *(is++)=Rmarg;
if (Super) { *(is++)=ESC; *(is++)='S'; *(is++)='0'; }
len=is-initstring;
if (Write(Prt,initstring,len)!=len) longjmp(Mains,ERROR);
return(0);
}
deinitprinter()
{
if (Let!='\f') if (Write(Prt,"\f",1)!=1) longjmp(Mains,ERROR);
if (PlBack){
DeinitPaper[DEINITLEN-1]=Plen; /* FF button works ok now */
if (Write(Prt,DeinitPaper,DEINITLEN)!=DEINITLEN) longjmp(Mains,ERROR);
}
return(0);
}
char *Inb, *Outb; /* two buffer pointer global from here on */
filetoprinter()
{
char inbuffer[IOBUFFER], outbuffer[IOBUFFER]; /* from the stack */
register int line, i;
register char c;
Inb=inbuffer; Outb=outbuffer;
i=Lmarg;
line=newpage();
while (1){
c=gc();
check:
if (c=='\t') i+=(SpPTab-((i-Lmarg)%SpPTab)); /* expand tabs */
else ++i;
if (c=='\n'){ /* newline */
i=Lmarg;
line=newline(line);
} else if (c=='\f'){ /* formfeed, newline inherent */
i=Lmarg;
line=newpage(line);
} else if (i>Rmarg){ /* R-marge reached: newline */
i=Lmarg;
line=newline(line);
if (Trunc) trunc(); /* skip rest of line */
else goto check; /* no, print rest on next line */
} else pc(c);
if (c==EOF) break;
}
return(0);
}
newline(line)
register int line;
{
++line;
if (line>=Page) line=newpage();
else pc('\n');
return(line);
}
trunc()
{
char t;
while ((t=gc())>=0) if (t=='\n') break;
return(0);
}
newpage()
{
static pagenr=0;
register out, factor, tpagenr, nr;
char ptd;
if ((pagenr)&&(Let!='\f')) ps("\r\f");
++pagenr;
if (Title){
out=0;
ps("page "); out+=5;
for (tpagenr=pagenr,factor=1000,ptd=0;factor;factor/=10){
if (nr=(tpagenr/factor)) ptd=1;
if (ptd){
pc(nr+0x30);
++out;
tpagenr-=(nr*factor);
}
}
for (;out<10;++out) pc(' ');
ps(Title); out+=strlen(Title);
factor=Cpline-strlen(Path[0])-Lmarg;
while (out++<factor) pc(' ');
ps(Path[0]);
ps("\n\n");
return(2); /* now two lines used */
}
return(0); /* no title; no lines used */
}
char gc() /* return a char, if buffer empty ask dos for more */
{
static avail=0, pos=0;
if (avail==0){
if ((avail=Read(Infile,Inb,IOBUFFER))<1){
if (avail<0) longjmp(Mains,ERROR);
return(EOF);
}
pos=0;
}
--avail;
return(*(Inb+pos++));
} /* gc */
void ps(string)
register char *string;
{
while (*string) pc(*(string++));
}
pc(c) /* store a char, if buffer full, flush it */
char c;
{
static pos=0;
if (c!=EOF){
Let=*(Outb+pos++)=c;
if (pos<IOBUFFER) return(0);
}
if ((TestOffSwitch())||(SetSignal(0,0x3000)&0x3000)){
deinitprinter();
longjmp(Mains,STOP);
}
if (Write(Prt,Outb,pos)!=pos) longjmp(Mains,ERROR);
pos=0;
return(0);
} /* pc */